#ifndef	_SYSTEM_H
#define	_SYSTEM_H	1

#include <stdio.h>
#include "io.h"
#include "tlsf.h"

// #define null 0

// #define NULL 0

#define SOFT_VER          20210414

#define SDRAM           0x00000000
#define VIDEO_RAM_SIZE  0x00180000

#define SPIROM          0x40000000
#define CACHE_CTL       0x42000000
#define CACHE_CTL_MEM_SIZE       0
#define CACHE_CTL_CACHE_CFG      1
#define CACHE_CTL_FLUSH_CNT      2

#define IRQ             0x44000000

#define MYTIMER         0x46000000
#define MYTIMER_LOW              0
#define MYTIMER_HI               1

#define MYUART          0x48000000
#define SOFTSPI         0x4A000000
#define SOFTSPI_READ             0
#define SOFTSPI_WRITE            0
#define SOFTSPI_CS               1
#define SOFTSPI_READ4            1

#define VGA             0x4C000000

#define VGA_MODE_BLOCK           0
#define VGA_BASE                 1
#define VGA_CURSOR_X             2
#define VGA_CURSOR_Y             3

#define VGA_CUR_PIX     0x4C002000

#define VGA_BLT         0x4C004000

#define VGA_BLT_AUTO    0x4C006000

#define SWITCH_SCREEN_MEM_03 0x030000
#define SWITCH_DATA_YY_01    0x010000
#define SWITCH_TRANS_OFF_04  0x040000
#define SWITCH_TRANS_ON_05   0x050000

#define BLT_S_SWITCH            0
#define BLT_S_SETVAL            1
#define BLT_S_PATTERN           2
#define BLT_S_DESTX             3
#define BLT_S_SRC_ADDR          4
#define BLT_S_WIDTH_HEIGHT      5
#define BLT_S_DRAW3D_PARAM      6
#define BLT_S_BASE_ADDR         7

#define BLT_M_RST_FIFO          8
#define BLT_M_WRITE_DATA_YY     9
#define BLT_M_3D_CACHE_REFRESH 10
#define BLT_M_WRITE_CB_CR      11
#define BLT_M_DESTY_DRAW3D_REQ 12
#define BLT_M_DESTY_MEMCPY_REQ 13
#define BLT_M_DESTY_MEMSET_REQ 14
#define BLT_M_DESTY_BUFWRI_REQ 15

//#define    0x7800
#define BLT_BUSY                 0



#define HID             0x4E000000
#define REG_SRAM        0x50000000
#define AUDIO           0x52000000
#define AUDIO_DATA               0
#define AUDIO_ENA                1
#define AUDIO_WRITE_USED         0
#define DS1302          0x54000000
#define DS1302_DATA              0
#define DS1302_CS                1
#define FPU             0x56000000
#define FPU_A_L                  0
#define FPU_A_H                  1
#define FPU_B_L                  2
#define FPU_B_H                  3
#define FPU_MUL_RESULT_L         0
#define FPU_MUL_RESULT_H         1
#define FPU_SFMUL_RESULT         2
#define FPU_SFDIV_RESULT         3
#define FPU_FMUL_RESULT_L        4
#define FPU_FMUL_RESULT_H        5
#define FPU_FDIV_RESULT_L        6
#define FPU_FDIV_RESULT_H        7
#define DEBUGGER        0x58000000
#define DEBUGGER_FLG_SYSTEM_VER  0
#define DEBUGGER_TXRX            1
#define CH375B          0x5A000000
#define CH375B_DAT               0
#define CH375B_DAT4              1
#define CH375B_A0                1
#define CH375B_CS                2
#define CH375B_RD                3
#define CH375B_WR                4

#define RND             0x5E000000

#define ALLIGN_1K __asm__ __volatile__(".ALLIGN_1K");


#define IRQ_PROC __attribute__((naked))
#define IRQ_PROLOG \
__asm__ __volatile__("addi	sp, sp, -120");\
__asm__ __volatile__("stw	r1 ,0(sp) ");\
__asm__ __volatile__("stw	ra ,4(sp) ");\
__asm__ __volatile__("stw	r2 ,8(sp) ");\
__asm__ __volatile__("stw	r3 ,12(sp)");\
__asm__ __volatile__("stw	r4 ,16(sp)");\
__asm__ __volatile__("stw	r5 ,20(sp)");\
__asm__ __volatile__("stw	r6 ,24(sp)");\
__asm__ __volatile__("stw	r7 ,28(sp)");\
__asm__ __volatile__("stw	r8 ,32(sp)");\
__asm__ __volatile__("stw	r9 ,36(sp)");\
__asm__ __volatile__("stw	r10,40(sp)");\
__asm__ __volatile__("stw	r11,44(sp)");\
__asm__ __volatile__("stw	r12,48(sp)");\
__asm__ __volatile__("stw	r13,52(sp)");\
__asm__ __volatile__("stw	r14,56(sp)");\
__asm__ __volatile__("stw	r15,60(sp)");\
__asm__ __volatile__("stw	r16,64(sp)");\
__asm__ __volatile__("stw	r17,68(sp)");\
__asm__ __volatile__("stw	r18,72(sp)");\
__asm__ __volatile__("stw	r19,76(sp)");\
__asm__ __volatile__("stw	r20,80(sp)");\
__asm__ __volatile__("stw	r21,84(sp)");\
__asm__ __volatile__("stw	r22,88(sp)");\
__asm__ __volatile__("stw	r23,92(sp)");\
__asm__ __volatile__("stw	r24,96(sp)");\
__asm__ __volatile__("stw	r25,100(sp)");\
__asm__ __volatile__("stw	r26,104(sp)");\
__asm__ __volatile__("stw	r27,108(sp)");\
__asm__ __volatile__("stw	r28,112(sp)");\
__asm__ __volatile__("stw	ea,116(sp)");/*r29 is gp/ea */ \
/*r30 is sp */ 

#define IRQ_EPILOG 	\
__asm__ __volatile__("ldw	r1 ,0(sp) ");\
__asm__ __volatile__("ldw	ra ,4(sp) ");\
__asm__ __volatile__("ldw	r2 ,8(sp) ");\
__asm__ __volatile__("ldw	r3 ,12(sp)");\
__asm__ __volatile__("ldw	r4 ,16(sp)");\
__asm__ __volatile__("ldw	r5 ,20(sp)");\
__asm__ __volatile__("ldw	r6 ,24(sp)");\
__asm__ __volatile__("ldw	r7 ,28(sp)");\
__asm__ __volatile__("ldw	r8 ,32(sp)");\
__asm__ __volatile__("ldw	r9 ,36(sp)");\
__asm__ __volatile__("ldw	r10,40(sp)");\
__asm__ __volatile__("ldw	r11,44(sp)");\
__asm__ __volatile__("ldw	r12,48(sp)");\
__asm__ __volatile__("ldw	r13,52(sp)");\
__asm__ __volatile__("ldw	r14,56(sp)");\
__asm__ __volatile__("ldw	r15,60(sp)");\
__asm__ __volatile__("ldw	r16,64(sp)");\
__asm__ __volatile__("ldw	r17,68(sp)");\
__asm__ __volatile__("ldw	r18,72(sp)");\
__asm__ __volatile__("ldw	r19,76(sp)");\
__asm__ __volatile__("ldw	r20,80(sp)");\
__asm__ __volatile__("ldw	r21,84(sp)");\
__asm__ __volatile__("ldw	r22,88(sp)");\
__asm__ __volatile__("ldw	r23,92(sp)");\
__asm__ __volatile__("ldw	r24,96(sp)");\
__asm__ __volatile__("ldw	r25,100(sp)");\
__asm__ __volatile__("ldw	r26,104(sp)");\
__asm__ __volatile__("ldw	r27,108(sp)");\
__asm__ __volatile__("ldw	r28,112(sp)");\
__asm__ __volatile__("ldw	ea,116(sp)");/*r29 is gp/ea */ \
/*r30 is sp */ \
__asm__ __volatile__("addi	sp, sp, 120");\
__asm__ __volatile__("reti");

#define ALIGN_UP(x, n)   (((x) + ((n) - 1)) & ~((n) - 1))

#ifdef __cplusplus
extern "C"{
#endif

void systemInit();

int align(int idx, int alignment);

// #pragma GCC diagnostic ignored "-Wbuiltin-declaration-mismatch"
void* malloc(size_t size);
void* malloca(size_t size, size_t align);
void* realloc(void* __ptr, size_t __size);
//extern __ptr_t calloc __P ((size_t __nmemb, size_t __size));
void free(void* __ptr);
void mem_report();

void memInit(int vram_size);


void setIrq(void (*irq)(void), int enable);

int sti(int);

void abort(void);

//TODO 要加上sdram的偏移，和考虑私有空间的情况
//void jmp(int val);
//
//void setOff(int val);
//
//void setOffRear(int val);
inline void jmp(int val){
  __asm__ __volatile__("jmp %[input1]"::[input1]"r"(val));
}

inline void setOff(int val){
  __asm__ __volatile__("stoff %[input1], 1"::[input1]"r"(val));
}
inline void setOffRear(int val){
  __asm__ __volatile__("stoff %[input1], 0"::[input1]"r"(val));
}

void* __eof__();

void initMallocIndex();

// void* amallocAll(int* retSize, int endOfRAM, int alignment);

// void* mallocAll(int* retSize);
  
// void* amalloc(void* p, size_t size, int alignment);

void* _Znwm(int size);

void mfree(int size);

void refreshInsCache();
void flushDataCache();

int getSeed();
void rndSetSeed(unsigned int seed);
int rnd();
unsigned long long mul64bit(unsigned long long a, unsigned long long b);

void* __getRes__();

int uart_read_timeout(int timeout);

int uart_read();

int uart_write(int val);

void uart_irq_init();

int uart_print_byte(int val);

void SPI_CHIP_SELECT_HIGH();
void SPI_CHIP_SELECT_LOW(int chip);
int spiRec();
int spiRec32();
void spiSend(int data);

int getRGB565(int rgb888);
int getRGB565sep(int r, int g, int b);
void drawImg(void* srcAddr, int x, int y, int w, int h);
void paint(int x, int y, int w, int h, short color);
void paint_pattern(int x, int y, int w, int h, int color, int pattern);

int receiveDebugData();

void sendDebugData(int val);

int getSystemVer();
int getSoftVer();


int getMemSize();


int getCMOS(int index);

int setCMOS(int index, int val);

int getTime(char* datetime);

int setTime(char* datetime);


long long getTick();

long long getMicros();

long long getMills();

long long getSecond();

#ifdef __cplusplus
}
#endif
#endif
